<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!--
        部署新工程的配置文件修改步骤
        1、修改ContextName
        2、修改KAFKA_SERVER_LOCATION
        3、修改INFO_KAFKA_OUT->topic
     -->
    <!-- 工程、上下文名字 -->
    <property name="APPLICATION_NAME" value="${model.code}"/>
    <contextName>${r'${APPLICATION_NAME}'}</contextName>
    <!-- 日志最大的历史 30天 -->
    <property name="MAX_HISTORY" value="30"/>
    <!-- 定义日志文件 输出位置 -->
    <property name="LOG_DIR" value="${r'${catalina.home}'}/logs"/>
    <property name="KAFKA_SERVER_LOCATION" value="192.168.2.112:9092"/>

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger:%line] - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="WARN_FILE_OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器，只记录ERROR级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>WARN</level>
        </filter>

        <!-- 最常用的滚动策略，它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志输出位置  可相对、和绝对路径 -->
            <fileNamePattern>${r'${LOG_DIR}'}/%d{yyyy-MM-dd}/error-log.log</fileNamePattern>
            <!-- 可选节点，控制保留的归档文件的最大数量，超出数量就删除旧文件假设设置每个月滚动，且<maxHistory>是6，
            则只保存最近6个月的文件，删除之前的旧文件。注意，删除旧文件是，那些为了归档而创建的目录也会被删除-->
            <maxHistory>${r'${MAX_HISTORY}'}</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger:%line] - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="INFO_FILE_OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器，只记录ERROR级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

        <!-- 最常用的滚动策略，它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志输出位置  可相对、和绝对路径 -->
            <fileNamePattern>${r'${LOG_DIR}'}/%d{yyyy-MM-dd}/info-log.log</fileNamePattern>
            <!-- 可选节点，控制保留的归档文件的最大数量，超出数量就删除旧文件假设设置每个月滚动，且<maxHistory>是6
            则只保存最近6个月的文件，删除之前的旧文件。注意，删除旧文件是，那些为了归档而创建的目录也会被删除-->
            <maxHistory>${r'${MAX_HISTORY}'}</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger:%line] - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="KAFKA_APPENDER" class="com.github.danielwegener.logback.kafka.KafkaAppender">
        <encoder class="com.github.danielwegener.logback.kafka.encoding.LayoutKafkaMessageEncoder">
            <layout class="cn.xtits.xtf.common.log.XtPatternLayout">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %level %cn %ip %host %thread %logger %msg%n</pattern>
            </layout>
        </encoder>
        <!--队列名称-->
        <topic>applog</topic>
        <keyingStrategy class="com.github.danielwegener.logback.kafka.keying.LoggerNameKeyingStrategy"/>
        <deliveryStrategy class="com.github.danielwegener.logback.kafka.delivery.AsynchronousDeliveryStrategy"/>
        <!--设置kafka集群地址-->
        <producerConfig>bootstrap.servers=${r'${KAFKA_SERVER_LOCATION}'}</producerConfig>
        <!--设置producer的确认信号
        （1）acks=0： 设置为0表示producer不需要等待任何确认收到的信息。副本将立即加到socket  buffer并认为已经发送。没有任何保障可以保证此种情况下server已经成功接收数据，同时重试配置不会发生作用（因为客户端不知道是否失败）回馈的offset会总是设置为-1；
        （2）acks=1： 这意味着至少要等待leader已经成功将数据写入本地log，但是并没有等待所有follower是否成功写入。这种情况下，如果follower没有成功备份数据，而此时leader又挂掉，则消息会丢失。
        （3）acks=all： 这意味着leader需要等待所有备份都成功写入日志，这种策略会保证只要有一个备份存活就不会丢失数据。这是最强的保证。
        -->
        <producerConfig>acks=0</producerConfig>
        <!--等待1秒后，一次发送所有消息-->
        <producerConfig>linger.ms=1000</producerConfig>
        <!--当我们内存缓存用尽时，必须停止接收新消息记录或者抛出错误。默认情况下，这个设置为真，然而某些阻塞可能不值得期待，因此立即抛出错误更好。设置为false则会这样：producer会抛出一个异常错误：BufferExhaustedException， 如果记录已经发送同时缓存已满-->
        <producerConfig>block.on.buffer.full=false</producerConfig>
        <!--获取元数据的超时时间。元素据包含：topic，host，partitions。此项配置是指当等待元素据fetch成功完成所需要的时间，否则会抛出异常给客户端。-->
        <producerConfig>metadata.fetch.timeout.ms=100</producerConfig>

        <!--若kafka传输失败，将这个appender下打印日志。-->
        <appender-ref ref="STDOUT"/>
    </appender>
    <springProfile name="test,onlinetest">
        <root level="INFO">
            <!-- 生产环境［不］配置此Appender -->
            <appender-ref ref="STDOUT"/>
        </root>
    </springProfile>
    <springProfile name="prod">
        <root level="INFO">
            <!-- 生产环境需要配置此Appender -->
            <appender-ref ref="INFO_FILE_OUT"/>
            <!-- 生产环境需要配置此Appender -->
            <appender-ref ref="WARN_FILE_OUT"/>
            <!-- 生产环境需要配置此Appender（开发环境可以不配） -->
            <appender-ref ref="KAFKA_APPENDER"/>
        </root>
    </springProfile>
</configuration>